﻿using System;

namespace Zo.Collections
{
    /// <summary>
    /// 字节队列。
    /// </summary>
    public class ByteQueue
    {
        private readonly byte[] _bytes;

        /// <summary>
        /// 位置。
        /// </summary>
        private int _index = 0;

        /// <summary>
        /// 每项的位置集合。
        /// </summary>
        private readonly int[] _itemIndexList;

        /// <summary>
        /// 集合序号。
        /// </summary>
        private int _itemIndex = 0;

        /// <summary>
        /// 初始化。
        /// </summary>
        /// <param name="maxSize">最大字节数。</param>
        /// <param name="itemCount">数据块的总数。</param>
        public ByteQueue(int maxSize, int itemCount)
        {
            _bytes = new byte[maxSize];
            _itemIndexList = new int[itemCount];
        }

        public byte[] Data => _bytes;

        public void Add(byte[] data)
        {
            if (data == null)
                return;

            // 将 data 填充到 _bytes 里，索引是 _index 开始。
            data.CopyTo(_bytes, _index);

            _itemIndexList[_itemIndex] = _index;

            _index += data.Length;
            _itemIndex++;
        }

        /// <summary>
        /// 获得指定序号的块数据。
        /// </summary>
        /// <remarks>
        /// --------------------------------------------------------------------
        /// [ 数据块 4 byte 序号 1 | 数据块 4 byte 序号 2 | 数据块 4 byte 序号 3
        /// --------------------------------------------------------------------
        /// </remarks>
        /// <param name="index">序号。</param>
        /// <returns>块数据。</returns>
        public byte[] Get(int index)
        {
            if (index > _itemIndex)
                throw new ArgumentOutOfRangeException(nameof(index));

            var startIndex = _itemIndexList[index];
            var length = _index;

            if (index < _itemIndex - 1)
            {
                length = _itemIndexList[index + 1] - startIndex;
            }
            else
            {
                length = length - startIndex;
            }

            var data = new byte[length];

            Array.Copy(_bytes, startIndex, data, 0, length);

            return data;
        }
    }
}